﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.IO;
using EnvDTE;
using System.Collections.ObjectModel;
using EnvDTE90;
using NArrange.Core;
using VSLangProj;
using EnvDTE80;

namespace WyoCode.WyoApp_VSTools.WCFManager
{




    /// <summary>
    /// Interaction logic for WCFRoot.xaml
    /// </summary>
    public partial class WCFRoot : UserControl
    {



        public VSProjectFile Project
        {
            get { return (VSProjectFile)GetValue(ProjectProperty); }
            set { SetValue(ProjectProperty, value); Refresh(); }
        }



        // Using a DependencyProperty as the backing store for Project.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ProjectProperty =
            DependencyProperty.Register("Project", typeof(VSProjectFile), typeof(WCFRoot), new UIPropertyMetadata(null));




        public WCFRoot()
        {
            InitializeComponent();
        }

        private void Refresh()
        {

            //load sl projects
            if (Project != null)
            {
                SLList.IsEnabled = true;
                SLList.ItemsSource = null;
                SLList.ItemsSource = Project.GetSilverlightProjects();
                if (SLList.Items.Count > 0)
                {
                    SLList.SelectedIndex = 0;
                }
            }
            else
            {
                SLList.IsEnabled = false;
            }




            this.ECList.IsEnabled = true;
            this.GenButton.IsEnabled = true;

            if (Project == null || Project.EDMXFiles.Count == 0)
            {
                this.ECList.IsEnabled = false;
                this.GenButton.IsEnabled = false;
                this.ECList.SelectionChanged -= new SelectionChangedEventHandler(ECList_SelectionChanged);

            }
            else if (Project != null)
            {

                this.ECList.ItemsSource = Project.EDMXFiles;
                this.ECList.SelectedIndex = 0;
                this.ECList.SelectionChanged += new SelectionChangedEventHandler(ECList_SelectionChanged);

                ((VSEdmxFile)this.ECList.SelectedItem).Load();
                this.EdmxList.ItemsSource = ((VSEdmxFile)this.ECList.SelectedItem).Entities;

                this.EdmxList.SelectionChanged += (s, evt) =>
                {
                    this.AllListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).All);
                    this.ReadListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Read);

                    this.WriteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Write);
                    this.DeleteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Delete);
                };


            }
            if (this.ECList.IsEnabled)
            {

            }
        }

        void ECList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {



            try
            {

                ((VSEdmxFile)this.ECList.SelectedItem).Load();
                this.EdmxList.ItemsSource = ((VSEdmxFile)this.ECList.SelectedItem).Entities;


                //((EntitySet)this.EdmxList.SelectedItem)
                this.EdmxList.SelectionChanged += (s, evt) =>
                    {
                        this.AllListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).All);
                        this.ReadListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Read);
                        this.WriteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Write);
                        this.DeleteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Delete);
                    };
            }
            catch { }

        }

        private void GenerateClick(object sender, RoutedEventArgs e)
        {
            try
            {

                // look here for templates

                //%LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\<Company>\<Product>\<Version>

                var apppath = AppInfo.GetStoreFolder();

#if DEBUG
                apppath = "";
#endif

                //Project.DTE_Project.DTE.StatusBar.Progress(true, "Building WCF Service");

                ProjectItem pi = null;

                System.Diagnostics.Process cassinipro = null;

                //string path = ((Solution3)WyoApp_VSToolsPackage._applicationObject.Solution).GetProjectItemTemplate("SLWcfService.zip", "CSharp/Web");


                pi = Project.DTE_Project.DTE.Solution.FindProjectItem(((VSEdmxFile)this.ECList.SelectedItem).FileName);






                Project.Configs.FirstOrDefault(c => c.RootCFG).AddLogging();


                var codefileloc = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Project.DTE_Project.FullName), Path.GetFileNameWithoutExtension(pi.Name) + ".ria.cs");
                if (File.Exists(codefileloc))
                {
                    File.Delete(codefileloc);
                }


                TemplateEngine wcfroot = new TemplateEngine(File.ReadAllText(Path.Combine(apppath, @"Templates\WCFCore.txt")));
                wcfroot.SetVar("namespace", Project.Namespace);
                wcfroot.SetVar("wcfclass", System.IO.Path.GetFileNameWithoutExtension(pi.Name));
                wcfroot.SetVar("dataentityclass", ((VSEdmxFile)this.ECList.SelectedItem).GetEntityContainer());
                StringBuilder sb = new StringBuilder();
                foreach (var item in ((VSEdmxFile)this.ECList.SelectedItem).Entities)
                {
                    sb.Append(item.GetEntityCode(((VSEdmxFile)this.ECList.SelectedItem).GetEntityContainer()) + Environment.NewLine + Environment.NewLine);
                }

                wcfroot.SetVar("datamethods", sb.ToString());

                //File.Delete(codefileloc);
                File.WriteAllText(codefileloc, wcfroot.ToString());
                pi.ProjectItems.AddFromFile(codefileloc);

                ((VSProject)Project.DTE_Project.Object).References.Add("System.ComponentModel.DataAnnotations");
                ((VSProject)Project.DTE_Project.Object).References.Add("System.ServiceModel.DomainServices.EntityFramework");
                ((VSProject)Project.DTE_Project.Object).References.Add("System.ServiceModel.DomainServices.Hosting");
                ((VSProject)Project.DTE_Project.Object).References.Add("System.ServiceModel.DomainServices.Hosting.OData");
                ((VSProject)Project.DTE_Project.Object).References.Add("System.ServiceModel.DomainServices.Server");



                var useradminfile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Project.DTE_Project.FullName), "UserAdminService.cs");
                if (File.Exists(useradminfile))
                {
                    File.Delete(useradminfile);
                }
                TemplateEngine useradminroot = new TemplateEngine(File.ReadAllText(@"Templates\UserAdminService.txt"));
                useradminroot.SetVar("namespace", Project.Namespace);
                File.WriteAllText(useradminfile, useradminroot.ToString());
                Project.DTE_Project.ProjectItems.AddFromFile(useradminfile);

                //((VSProject)Project.DTE_Project.Object).BuildManager.BuildDesignTimeOutput("");
                //Project.DTE_Project.DTE.ExecuteCommand("Build.BuildSolution");
                //Project.DTE_Project.DTE.Solution.SolutionBuild.BuildProject(Project.DTE_Project.DTE.Solution.SolutionBuild.ActiveConfiguration.Name, Project.DTE_Project.UniqueName, true);
                //((VsWebSite.VSWebSite)Project.DTE_Project.Object).EnsureServerRunning();

                // start cassini

                //taskkill /F /IM WebDev.WebServer.exe

                //START /D “C:\Program Files\Common Files\microsoft shared\DevServer\9.0\” /B WebDev.WebServer.EXE /port:5002 /path:”d:\Projects\myproject\project.service”

                cassinipro = new System.Diagnostics.Process();
                cassinipro.StartInfo = new System.Diagnostics.ProcessStartInfo();


                cassinipro.StartInfo.FileName = Path.Combine(GetProgramFiles(), @"Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE");
                cassinipro.StartInfo.Arguments = "/vpath:" + Project.WebDevDir + " /port:" + Project.WebDevPort + " /path:\"" + System.IO.Path.GetDirectoryName(Project.DTE_Project.FullName) + "\"";

                //cassinipro.Start();




                if (SLList.SelectedItem != null)
                {

                    //Project.DTE_Project.DTE.StatusBar.Progress(true, "Building Silverlight helpers");

                    var pro = ((VSSLProject)SLList.SelectedItem).Project;




                    TemplateEngine slappcore = new TemplateEngine(File.ReadAllText(Path.Combine(apppath, @"Templates\AppCore.txt")));
                    slappcore.SetVar("wcfname", System.IO.Path.GetFileNameWithoutExtension(pi.Name));
                    slappcore.SetVar("namespace", pro.Name);

                    StringBuilder slsb = new StringBuilder();
                    foreach (var item in ((VSEdmxFile)this.ECList.SelectedItem).Entities)
                    {
                        slsb.Append(item.GetSLCode());
                    }

                    slappcore.SetVar("methods", slsb.ToString());





                    var appcorepath = Path.Combine(Path.GetDirectoryName(pro.FullName), "AppCore.cs");
                    if (File.Exists(appcorepath))
                    {
                        // overwrite
                        File.Delete(appcorepath);
                        File.WriteAllText(appcorepath, slappcore.ToString());
                    }
                    else
                    {
                        // add file
                        File.WriteAllText(appcorepath, slappcore.ToString());
                        pro.ProjectItems.AddFromFile(appcorepath);
                        pro.Save();
                    }


                    // get all dirs in Templates

                    foreach (var dir in Directory.GetDirectories(Path.Combine(apppath, @"Templates")))
                    {

                        foreach (var file in Directory.GetFiles(dir, "*.*t"))
                        {
                            TemplateEngine filetemp = new TemplateEngine(File.ReadAllText(file));
                            filetemp.SetVar("webnamespace", Project.Namespace);
                            filetemp.SetVar("namespace", pro.Name);
                            // get file dir out
                            try
                            {
                                pro.ProjectItems.AddFolder(dir.Replace("Templates\\", ""));
                            }
                            catch { }

                            var filepath = Path.Combine(Path.GetDirectoryName(pro.FullName), file.Replace("Templates\\", "").TrimEnd('t'));
                            if (!Directory.Exists(Path.Combine(Path.GetDirectoryName(pro.FullName), dir)))
                            {
                                Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(pro.FullName), dir));

                            }
                            if (File.Exists(filepath))
                            {
                                File.Delete(filepath);
                            }
                            File.WriteAllText(filepath, filetemp.ToString());
                            pro.ProjectItems.AddFromFile(filepath);
                        }



                    }



                    //var slurl = new Uri(new Uri(Project.WebURL), Path.GetFileNameWithoutExtension(pi.Name) + ".svc");




                    //Project.DTE_Project.DTE.ExecuteCommand("Project.AddServiceReference");





                    //http://msdn.microsoft.com/en-us/library/x6h10s6x(VS.100).aspx


                    //compile web 

                    // add web service
                    //svcutil <endpoint> 
                    // C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 
                    // svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8000/ServiceModelSamples/service /async

                    // kill cassini
                    //var refrencepath = Path.Combine(Path.GetDirectoryName(pro.FullName), Path.GetFileNameWithoutExtension(pi.Name) + "ServiceProxy.cs");
                    //var configpath = Path.Combine(Path.GetDirectoryName(pro.FullName), "ServiceReferences.ClientConfig");
                    //var args = "/language:cs /out:\"" + refrencepath + "\" " + slurl.AbsoluteUri + "?wsdl /config:\"" + configpath + "\" /edb";
                    ////Project.DTE_Project.DTE.StatusBar.Progress(true, "Adding Service refrence");






                    //var svcutilpro = new System.Diagnostics.Process();
                    //svcutilpro.StartInfo = new System.Diagnostics.ProcessStartInfo();


                    //    svcutilpro.StartInfo.FileName = Path.Combine(GetProgramFiles(), @"Microsoft SDKs\Silverlight\v4.0\Tools\slsvcutil.exe");



                    //svcutilpro.StartInfo.Arguments = args;
                    //svcutilpro.StartInfo.UseShellExecute = false;
                    //if (svcutilpro.StartInfo.FileName != null || svcutilpro.StartInfo.FileName != "")
                    //{
                    //    svcutilpro.Start();
                    //    svcutilpro.WaitForExit();
                    //}

                    //try
                    //{
                    //    pro.ProjectItems.AddFromFile(refrencepath);
                    //    pro.ProjectItems.AddFromFile(configpath);
                    //    ((VSProject)pro.Object).References.Add("System.Runtime.Serialization");
                    //    ((VSProject)pro.Object).References.Add("System.ServiceModel");
                    //}
                    //catch
                    //{
                    //    MessageBox.Show("Unable to auto add service refrence please add a refrence with namespace " + Path.GetFileNameWithoutExtension(pi.Name) + "Service");
                    //    Clipboard.SetText(Path.GetFileNameWithoutExtension(pi.Name) + "Service");
                    ////}


                }

                Project.DTE_Project.DTE.ExecuteCommand("Build.BuildSolution");
                // if (cassinipro != null && !cassinipro.HasExited) cassinipro.Kill();
                //Project.DTE_Project.DTE.StatusBar.Progress(false);


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            Refresh();
        }

        private void AddSecurityToEntity(object sender, RoutedEventArgs e)
        {
            var filename = ((EntitySet)this.EdmxList.SelectedItem).SetName + ".seccfg";
            var tempfile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), filename);
            var outitem = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Project.ProjectLoc), filename);
            if (File.Exists(outitem))
            {
                File.Delete(outitem);
            }
            ((EntitySet)this.EdmxList.SelectedItem).SaveToFile(tempfile);
            // find 
            ProjectItem pi = null;
            foreach (ProjectItem item in Project.DTE_Project.ProjectItems)
            {
                if (item.Name == ((VSEdmxFile)this.ECList.SelectedItem).FileName)
                {
                    pi = item;
                    break;
                }
            }
            pi.ProjectItems.AddFromFileCopy(tempfile);


            //Project.DTE_Project.ProjectItems.AddFromFileCopy(tempfile);

            File.Delete(tempfile);
        }

        private void AddGroupAll(object sender, RoutedEventArgs e)
        {
            if (!((EntitySet)this.EdmxList.SelectedItem).All.Contains(AddGroupTBAll.Text))
            {
                ((EntitySet)this.EdmxList.SelectedItem).All.Add(AddGroupTBAll.Text);
                this.AllListBox.ItemsSource = null;
                this.AllListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).All);

                AddGroupTBAll.Text = "";
            }
        }

        private void DelGroupAll(object sender, RoutedEventArgs e)
        {
            if (this.AllListBox.SelectedItem != null)
            {
                ((EntitySet)this.EdmxList.SelectedItem).All.Remove((string)this.AllListBox.SelectedItem);

                this.AllListBox.ItemsSource = null;
                this.AllListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).All);

            }
        }

        private void AddGroupRead(object sender, RoutedEventArgs e)
        {
            if (!((EntitySet)this.EdmxList.SelectedItem).Read.Contains(AddGroupTBRead.Text))
            {
                ((EntitySet)this.EdmxList.SelectedItem).Read.Add(AddGroupTBRead.Text);
                this.ReadListBox.ItemsSource = null;
                this.ReadListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Read);

                AddGroupTBRead.Text = "";
            }
        }

        private void DelGroupRead(object sender, RoutedEventArgs e)
        {
            if (this.ReadListBox.SelectedItem != null)
            {
                ((EntitySet)this.EdmxList.SelectedItem).Read.Remove((string)this.ReadListBox.SelectedItem);

                this.ReadListBox.ItemsSource = null;
                this.ReadListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Read);

            }
        }

        private void AddGroupWrite(object sender, RoutedEventArgs e)
        {
            if (!((EntitySet)this.EdmxList.SelectedItem).Write.Contains(AddGroupTBWrite.Text))
            {
                ((EntitySet)this.EdmxList.SelectedItem).Write.Add(AddGroupTBWrite.Text);
                this.WriteListBox.ItemsSource = null;
                this.WriteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Write);

                AddGroupTBWrite.Text = "";
            }
        }

        private void DelGroupWrite(object sender, RoutedEventArgs e)
        {
            if (this.WriteListBox.SelectedItem != null)
            {
                ((EntitySet)this.EdmxList.SelectedItem).Write.Remove((string)this.WriteListBox.SelectedItem);

                this.WriteListBox.ItemsSource = null;
                this.WriteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Write);

            }
        }



        private void AddGroupDelete(object sender, RoutedEventArgs e)
        {
            if (!((EntitySet)this.EdmxList.SelectedItem).Delete.Contains(AddGroupTBDelete.Text))
            {
                ((EntitySet)this.EdmxList.SelectedItem).Delete.Add(AddGroupTBDelete.Text);
                this.DeleteListBox.ItemsSource = null;
                this.DeleteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Delete);

                AddGroupTBDelete.Text = "";
            }
        }

        private void DelGroupDelete(object sender, RoutedEventArgs e)
        {
            if (this.DeleteListBox.SelectedItem != null)
            {
                ((EntitySet)this.EdmxList.SelectedItem).Delete.Remove((string)this.DeleteListBox.SelectedItem);

                this.DeleteListBox.ItemsSource = null;
                this.DeleteListBox.ItemsSource = new ObservableCollection<string>(((EntitySet)this.EdmxList.SelectedItem).Delete);

            }
        }


        static string GetProgramFiles()
        {
            if (8 == IntPtr.Size
                || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"))))
            {
                return Environment.GetEnvironmentVariable("ProgramFiles(x86)");
            }

            return Environment.GetEnvironmentVariable("ProgramFiles");
        }

    }
}
